home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / Amiga_Mail_Vol2 / Archives / Plain / jf93 / ASCII / BoopsiV39 / BoopsiV39.txt < prev    next >
Encoding:
Text File  |  1993-03-01  |  25.3 KB  |  550 lines

  1. (c) Copyright 1993 Commodore-Amiga, Inc.   All rights reserved.
  2. The information contained herein is subject to change without notice,
  3. and is provided "as is" without warranty of any kind, either expressed
  4. or implied.  The entire risk as to the use of this information is
  5. assumed by the user.
  6.  
  7.  
  8. Boopsi in Release 3
  9.  
  10. by John Orr and Peter Cherna
  11.  
  12.  
  13.  
  14. For Release 3, Intuition gained significant improvements that
  15. directly affect Intuition's object oriented programming subsystem,
  16. Boopsi.  Intuition now has gadget help features, bounding boxes for
  17. gadgets and their imagery, special custom layout gadgetry, and
  18. several other features that all have an impact on Boopsi.
  19.  
  20. This article assumes that the reader already has a basic
  21. understanding of Boopsi and the object oriented programming model.
  22. For those not comfortable with these concepts, see the
  23. ``Boopsi--Object Oriented Intuition'' chapter of the ROM Kernel
  24. Reference Manual: Libraries.
  25.  
  26.  
  27. DoGadgetMethodA()
  28.  
  29. One Boopsi-related function added to intuition.library for Release 3
  30. is DoGadgetMethodA():
  31.  
  32.     ULONG DoGadgetMethodA(struct Gadget *object, struct Window *win,
  33.                           struct Requester *req, Msg msg);
  34.  
  35. This function is similar to amiga.lib's DoMethod(), except
  36. DoGadgetMethod() passes along the object's graphical environment in
  37. the form of a GadgetInfo structure.  DoGadgetMethodA() gets this
  38. structure from the gadget's window (or requester).  The GadgetInfo
  39. structure is important because a Boopsi gadget needs the information
  40. in that structure to render itself.  Note that if you give
  41. DoGadgetMethodA() a NULL Window and NULL Requester pointer,
  42. DoGadgetMethodA() will pass a NULL GadgetInfo pointer.
  43.  
  44. The name and first parameter of DoGadgetMethodA() may lead you to
  45. believe that this function applies only to gadgets.  Although you can
  46. certainly use this function on gadget objects, the function is not
  47. restricted to gadget objects.  You can use this function on any
  48. Boopsi object.  This is important for an object such as a model
  49. object, which may react to any Boopsi message by invoking some method
  50. on gadget objects connected to it.  Because the model object receives
  51. environment information in the form of a GadgetInfo structure, the
  52. model can pass that information on to any objects connected to it.
  53.  
  54. Before this function, passing the environment information was not
  55. that easy.  A good example of this is the rkmmodelclass example in
  56. the ``Boopsi--Object Oriented Intuition'' chapter of RKRM: Libraries
  57. (page 312-315).  In that example, the rkmmodelclass is a subclass of
  58. modelclass.  The rkmmodelclass object inherits the behavior of
  59. modelclass, so its sends updates to its member objects.  One feature
  60. rkmmodelclass adds to modelclass is that these objects maintain an
  61. internal integer value.  If that value changes, the rkmmodelclass
  62. object propagates that change to its member objects.
  63.  
  64. If one of the member objects happens to be a gadget object, changing
  65. the rkmmodelclass object's internal value may change the visual state
  66. of the gadgets.  For the gadget's to update their visual state, they
  67. need the environment information from the GadgetInfo structure as
  68. well as the new internal value of the rkmmodelclass object.  If an
  69. application used DoMethod() or SetAttrs() to set the rkmmodelclass
  70. object's internal value, the rkmmodelclass object would not get a
  71. GadgetInfo structure.  When the rkmmodelclass object propagates the
  72. internal value change to its member objects, it has no environment
  73. information to pass on to its member objects.  As a result, the
  74. member gadgets can not update their visual state directly.  This is
  75. particularly annoying for a propgclass object, because the visual
  76. state of the propgclass object can depend on the rkmmodelclass
  77. object's integer value.
  78.  
  79. DoGadgetMethodA() corrects this problem.  It passes a pointer to a
  80. GadgetInfo structure for the window (or requester) you pass to it.
  81. If you plan on implementing new Boopsi methods that need a GadgetInfo
  82. structure in their Boopsi message, make sure the second long word of
  83. the Boopsi message is a pointer to the GadgetInfo structure.
  84. DoGadgetMethodA() assumes that every method (except for OM_NEW,
  85. OM_SET, OM_NOTIFY, and OM_UPDATE; see the next paragraph) expects a
  86. GadgetInfo pointer in that place.
  87.  
  88. Iif you use DoGadgetMethodA() to send an OM_SET message to a Boopsi
  89. gadget, DoGadgetMethodA() passes a pointer to a GadgetInfo structure
  90. as the third long word in the Boopsi message.  DoGadgetMethodA() is
  91. smart enough to know that the OM_SET method uses an opSet structure
  92. as its message, which has a pointer to a GadgetInfo structure as its
  93. third long word.  DoGadgetMethodA() passes a GadgetInfo structure as
  94. the third parameter for the OM_NEW, OM_SET, OM_NOTIFY, and OM_UPDATE
  95. methods.  For all other methods, like the gadgetclass methods,
  96. DoGadgetMethodA() passes a GadgetInfo structure as the second long
  97. word.  For more information, see the V39 Autodoc for
  98. DoGadgetMethodA() and its varargs equivalent, DoGadgetMethod().
  99.  
  100.  
  101. Bounding Boxes for Gadgets
  102.  
  103. Before Release 3, gadgets only had a select (or hit) box.  This box
  104. is the area of the window that the user can click in to select the
  105. gadget.  The select box limits certain gadgets because the gadget's
  106. imagery could lie outside of the gadget's hit box.  For example, the
  107. hit box for a string gadget is the area that text appears when the
  108. user types into the gadget (see Figure 1).  Many string gadgets have
  109. a border and a label, which the programmer sets using the Gadget
  110. structure's GadgetRender and GadgetText fields.  The border and label
  111. imagery appears outside of the hit box.
  112.  
  113.  
  114.         [Figure 1]
  115.  
  116.  
  117. The major disadvantage of a gadget's imagery being external to its
  118. hit box has to do with relative gadgets (these are sometimes referred
  119. to as GREL gadgets).  Intuition positions one of these gadgets
  120. relative to the edge's of the gadget's window.  When the window
  121. changes dimensions, Intuition repositions the gadget within the
  122. window.  The gadget can also make its size relative to the window's
  123. dimensions.
  124.  
  125. When Intuition resizes a window, it remembers which portions of the
  126. window's display sustained visual damage.  When Intuition refreshes
  127. the visual state of the window, it only redisplays the parts of the
  128. window that sustained visual damage.  When Intuition resizes a window
  129. that has a GREL gadget, Intuition erases the old gadget by erasing
  130. the hit box of the gadget and remembers that area as a region it will
  131. have to refresh.  Intuition also figures out where the the new hit
  132. box will be and remembers that area as a region Intuition will have
  133. to refresh.  Because Intuition will not erase or redraw any imagery
  134. that falls outside of the GREL gadget's hit box, Intuition will
  135. ignore any part of the gadget's label or border that is outside the
  136. hit box.
  137.  
  138. To remedy this situation, Intuition added a bounding box to gadgets.
  139. If a gadget has a bounding box, Intuition uses the bounding box in
  140. place of the hit box when figuring out what areas to refresh.  With a
  141. bounding box, a gadget can extend its hit area to encompass all of
  142. its imagery.
  143.  
  144. The bounding box feature is not specific to Boopsi gadgets.  Any
  145. Intuition gadget can have one.  If the gadget doesn't supply a
  146. bounding box, Intuition will use the gadget's normal hit box as the
  147. bounding box, which yields the same result as previous versions of
  148. the OS.
  149.  
  150. Adding the bounding box feature to Intuition gadgets required
  151. extending the Gadget structure.  There is a new structure called
  152. ExtGadget that is a superset of the old Gadget structure (from
  153. <intuition/intuition.h>):
  154.  
  155. struct ExtGadget
  156. {
  157.     /* The first fields match struct Gadget exactly */
  158.     struct ExtGadget *NextGadget; /* Matches struct Gadget */
  159.     WORD LeftEdge, TopEdge;       /* Matches struct Gadget */
  160.     WORD Width, Height;           /* Matches struct Gadget */
  161.     UWORD Flags;                  /* Matches struct Gadget */
  162.     APTR SpecialInfo;             /* Matches struct Gadget */
  163.     UWORD GadgetID;               /* Matches struct Gadget */
  164.     APTR UserData;                /* Matches struct Gadget */
  165.  
  166.     /* These fields only exist under V39 and only if GFLG_EXTENDED is set */
  167.     ULONG MoreFlags;
  168.     WORD BoundsLeftEdge;        /* Bounding extent for gadget, valid */
  169.     WORD BoundsTopEdge;         /* only if the GMORE_BOUNDS bit in   */
  170.                                 /*  the MoreFlags field is set.  The */
  171.     WORD BoundsWidth;           /* GFLG_RELxxx flags affect these    */
  172.     WORD BoundsHeight;          /* coordinates as well.              */
  173. };
  174.  
  175.  
  176. Intuition discerns a Gadget from an ExtGadget by testing the Flags
  177. field.  If the GFLG_EXTENDED bit is set, the Gadget structure is
  178. really an ExtGadget structure.  Intuition will use the bounding box
  179. only if the GMORE_BOUNDS bit in the ExtGadget.MoreFlags field is set.
  180.  
  181. Gadgetclass supports an attribute called GA_Bounds that sets up a
  182. Boopsi gadget's bounding box.  It expects a pointer to an IBox
  183. structure (from <intuition/intuition.h>) in the ti_Data field, which
  184. gadgetclass copies into the bounding box fields in the ExtGadget
  185. structure.
  186.  
  187.  
  188. Gadget Help
  189.  
  190. Intuition V39 introduces a help system designed around Intuition
  191. gadgets.  Window-based applications can elect to receive a new type
  192. of IDCMP message called IDCMP_GADGETHELP when the user positions the
  193. pointer over one of the window's gadgets.  The pointer is over the
  194. gadget if the pointer is within the gadget's bounding box (which
  195. defaults to the gadget's hit box).
  196.  
  197. Using the intuition.library function HelpControl(), an application
  198. can turn Gadget Help on and off for a window:
  199.  
  200.   VOID HelpControl(struct Window *my_win, ULONG help_flags);
  201.  
  202. Currently, the only flag defined for the help_flags field is
  203. HC_GADGETHELP (from <intuition/intuition.h>).  If the HC_GADGETHELP
  204. bit is set, HelpControl() turns on help for my_win, otherwise
  205. HelpControl() turns off gadget help for the window.
  206.  
  207. When gadget help is on for the active window, Intuition sends
  208. IDCMP_GADGETHELP messages to the window's IDCMP port.  Each time the
  209. user moves the pointer from one gadget to another, Intuition sends an
  210. IDCMP_GADGETHELP message about the new gadget.  Intuition also sends
  211. an IDCMP_GADGETHELP message when the user positions the pointer over
  212. a gadgetless portion of the window, and when the user moves the
  213. pointer outside of the window. An application can find out what
  214. caused the IDCMP_GADGETHELP message by first examining the
  215. IntuiMessage's IAddress field.  If IAddress is NULL, the pointer is
  216. outside of the window.  If IAddress is the window address, the
  217. pointer is inside of the window, but not over any gadget.  If
  218. IAddress is some other value, the user positioned the pointer over
  219. one of the window's gadgets and IAddress is the address of that
  220. gadget.
  221.  
  222. To discern between the different system gadgets (window drag bar,
  223. window close gadget, etc.) an application has to check the GadgetType
  224. field of the gadget:
  225.  
  226.     #define GTYP_SYSTYPEMASK 0xF0   /* This constant did not appear in */
  227.                                     /* earlier V39 include files.      */
  228.  
  229.     sysgtype = ((struct Gadget *)imsg->IAddress)->GadgetType & GTYP_SYSTYPEMASK;
  230.  
  231. The constant GTYP_SYSTYPEMASK  (defined in <intuition/intuition.h>)
  232. corresponds to the bits of the GadgetType field used for the system
  233. gadget type.  There are several possible values for sysgtype (defined
  234. in <intuition/intuition.h>):
  235.  
  236.     GTYP_SIZING        Window sizing gadget
  237.     GTYP_WDRAGGING    Window drag bar
  238.     GTYP_WUPFRONT        Window depth gadget
  239.     GTYP_WDOWNBACK    Window zoom gadget
  240.     GTYP_CLOSE        Window close gadget
  241.  
  242. If sysgtype is zero, IAddress is the address of an application's
  243. gadget.
  244.  
  245. Not all gadget's will trigger an IDCMP_GADGETHELP event.  Intuition
  246. will send gadget help events when the pointer is over a gadget with
  247. an extended Gadget structure (struct ExtGadget from
  248. <intuition/intuition.h>) and a set GMORE_GADGETHELP flag (from the
  249. ExtGadget.MoreFlags field).
  250.  
  251. To set or clear this flag for a Boopsi gadget, an application can use
  252. the GA_GadgetHelp attribute.  Setting GA_GadgetHelp to TRUE sets the
  253. flags and setting it to FALSE clears the flag.  Only the OM_SET
  254. method applies to this gadgetclass attribute.
  255.  
  256. To support gadget help, gadgetclass gained a new method called
  257. GM_HELPTEST.  This method uses the same message structure as
  258. GM_HITTEST, struct gpHitTest (defined in <intuition/gadgetclass.h>),
  259. and operates similarly to GM_HITTEST.  While a window is in help
  260. mode, when the user positions the pointer within the bounding box of
  261. a Boopsi gadget that supports gadget help, Intuition sends the gadget
  262. a GM_HELPTEST message.
  263.  
  264. Like the GM_HITTEST method, the GM_HELPTEST method asks a gadget if a
  265. point is within the gadget's bounds.  Like the GM_HITTEST method, the
  266. GM_HELPTEST method allows a Boopsi gadget to have a non-rectangular
  267. hit area (or in this case, a help area).  If the point is within the
  268. gadget, the gadget uses one of two return codes.  If the gadget
  269. returns a value of GMR_HELPHIT, Intuition places a value of 0xFFFF in
  270. the Code field of the IDCMP_GADGETHELP message. The gadget also has
  271. the option of using GMR_HELPCODE instead of GMR_HELPHIT.
  272. GMR_HELPCODE is a little peculiar as a return value.  Although
  273. GMR_HELPCODE is 32 bits long, Intuition identifies GMR_HELPCODE using
  274. only its upper 16 bits.  If the upper 16 bits of GM_HELPTEST's return
  275. value matches the upper 16 bits of GMR_HELPCODE, Intuition copies the
  276. lower word of the return value into the Code field of the
  277. IDCMP_GADGETHELP message.  The Boopsi gadget is free to set the
  278. return value's lower word to any 16-bit value.
  279.  
  280. If the point is not within the gadget's ``help spot'', the gadget
  281. returns GMR_NOHELPHIT.  Intuition will then look under that gadget
  282. for more gadgets.  If a gadget's dispatcher passes the GM_HELPTEST
  283. method on to the gadgetclass dispatcher, the gadgetclass dispatcher
  284. will always return GMR_HELPHIT.
  285.  
  286. An application can put several windows in the same help group.  This
  287. feature groups several windows so that as long as one of those
  288. windows is active, the application can receive IDCMP_GADGETHELP
  289. messages about all of those windows.  For more information, See the
  290. HelpControl() Autodoc and the WA_HelpGroup section of the
  291. OpenWindow() Autodoc (both are in intuition.doc).
  292.  
  293.  
  294. Boopsi Gadgets and ScrollRaster()
  295.  
  296. This section covers some fairly complicated aspects of Intuition
  297. Windows and how Intuition interacts with the Layers system.  For a
  298. more in depth explanation, see the article, ``Optimized Window
  299. Refreshing'' from the July/August 1992 issue of Amiga Mail.
  300.  
  301. Scrolling an Intuition display with ScrollRaster() is unlike many
  302. other rendering operations because it can damage a window layer.
  303. ScrollRaster() is both a rendering function and a layering function
  304. (ScrollRaster() is a graphics.library function, but it is aware of
  305. the Layers system).  If window X overlaps window Y, scrolling window
  306. Y can scroll a portion of window Y out from underneath window X:
  307.  
  308.  
  309.         [Figure 2a and 2b]
  310.  
  311.  
  312. For both smart refresh and super bitmap windows, this does not
  313. present a problem.  Layers remembers what was underneath window X and
  314. restores that portion of the display when a layers operation reveals
  315. it.  When a scrolling operation damages a smart refresh or super
  316. bitmap window, Layers repairs the display.
  317.  
  318.  
  319.          What is Layer Damage?
  320.  
  321.          The Layers definition of ``damage'' is a little
  322.          confusing.  Looking at the illustration, two areas of
  323.          window Y need to be refreshed: the area that used to be
  324.          underneath window X, and the area that was scrolled
  325.          into view at the bottom of window Y (the partially
  326.          visible ``RSTUVWXY'').  Layers considers only one of
  327.          these areas to be ``damaged'', the area the was
  328.          scrolled out from underneath window X. Layers considers
  329.          it damaged because the damage was caused by the
  330.          presence of another window layer.  The task that called
  331.          ScrollRaster() has no idea that there is an overlapping
  332.          window layer, so it is up to Layers to account for that
  333.          damage.  On the other hand, the task that called
  334.          ScrollRaster() knows that the area at the bottom of
  335.          window Y needs refreshing, so the task knows to fix
  336.          that area of the window.  To Layers, damage is the area
  337.          of a layer that needs refreshing as a result of layers
  338.          operation.
  339.  
  340.  
  341. For a simple refresh window, Layers remembers which portion of the
  342. window layer is damaged.  Layers does nothing to repair the damage.
  343. Layers leaves repairing the damage to Intuition.  After performing a
  344. layers operation on a window (such as scrolling a portion of a
  345. window), Intuition must check if that operation caused layer damage
  346. (either to that window or other windows on the display).
  347.  
  348. In Release 2, when Intuition told a scrolling Boopsi gadget to render
  349. itself, Intuition did not check for layer damage.  If that gadget
  350. damaged the display with the ScrollRaster() function, Intuition did
  351. not repair that damage.
  352.  
  353. As of Release 3.0, Intuition has a flag set aside in the MoreFlags
  354. field of the ExtGadget structure called GMORE_SCROLLRASTER (defined
  355. in <intuition/intuition.h>).  If this flag is set, when the gadget
  356. damages the display with ScrollRaster() (or ScrollRasterBF()),
  357. Intuition redraws all GMORE_SCROLLRASTER gadgets in the damaged
  358. window.  The class dispatcher should take care of setting this flag
  359. when creating the gadget in the OM_NEW method.
  360.  
  361. ScrollRaster() is not the only function in Release 3 that can scroll
  362. a window's contents.  For Release 3, the Intuition library gained a
  363. function specifically to scroll a window's raster.  That function,
  364. ScrollWindowRaster(), is similar to ScrollRaster(), but
  365. ScrollWindowRaster() is Intuition-friendly.  Boopsi gadgets must not
  366. use this function, they should use ScrollRaster() or ScrollRasterBF()
  367. instead.  Also any applications that use GMORE_SCROLLRASTER gadgets
  368. must use ScrollWindowRaster() for scrolling.  Note that gadgets
  369. supplied by third parties or Commodore may be GMORE_SCROLLRASTER
  370. gadgets.  For more information on ScrollWindowRaster(), see its
  371. Autodoc.
  372.  
  373.  
  374. Smart Layout Gadgets
  375.  
  376. Prior to Release 3, Intuition took care of laying out GREL gadgets
  377. whenever the dimensions of the window change.  This was a limitation
  378. for a GREL Boopsi gadget that wants to perform its own layout.
  379. Because Intuition didn't tell the Boopsi gadget that the window's
  380. dimensions changed, the gadget cannot react to the change.
  381.  
  382. As of Release 3, Intuition uses a new gadget method called GM_LAYOUT
  383. to tell a GREL Boopsi gadget that its window's dimensions have
  384. changed.  The GM_LAYOUT method uses the gpLayout structure (defined
  385. in <intuition/gadgetclass.h>) as its message:
  386.  
  387. struct gpLayout
  388. {
  389.     ULONG                  MethodID;
  390.     struct GadgetInfo  *gpl_GInfo;
  391.     ULONG               gpl_Initial; /* This field is non-zero if this method was invoked
  392.                                       * during AddGList() or OpenWindow().  zero if this
  393.                                       * method was invoked during window resizing.
  394.                                       */
  395. };
  396.  
  397. For GREL gadgets, Intuition sends a GM_LAYOUT message just after
  398. erasing the gadget's bounding box.  Intuition does not touch the
  399. values of the gadget's bounding box or hit box, it lets the gadget
  400. handle recalculating these values.  Thee gadget can lay itself out
  401. based on the new window (or requester) dimensions found in the
  402. GadgetInfo structure passed in the GM_LAYOUT message (gpl_GInfo from
  403. the gpLayout structure).  Intuition also adds the old and new
  404. bounding box of the gadget to the window's damaged regions so that
  405. the gadget will appear is its new position.  The gadget must not
  406. perform any rendering inside the GM_LAYOUT method.  Intuition will
  407. send a GM_RENDER message to the gadget when its time to redraw the
  408. gadget in its new position.
  409.  
  410. There are two cases where Intuition sends a GM_LAYOUT message:
  411.  
  412.     When the gadget's window is resized
  413.     When Intuition adds the gadget to a window
  414.  
  415. There are two ways for a window to gain gadgets.  An application can
  416. explicitly add gadgets using the AddGList() function.  The window can
  417. also gain gadgets during it initialization in the OpenWindow() call.
  418.  
  419. For most GREL Boopsi gadgets, Intuition expects the values in the
  420. LeftEdge, TopEdge, Width, and Height fields to follow the existing
  421. convention for regular GREL gadgets.  Each of these fields has a flag
  422. in the Gadget.Flags field (GFLG_RELRIGHT, GFLG_RELBOTTOM,
  423. GFLG_RELWIDTH, and GFLG_RELHEIGHT, respectively).  If that field's
  424. flag is set, Intuition expects the value in that field to be relative
  425. to either the window border or the window dimensions.  For example,
  426. if GFLG_RELRIGHT is set, Intuition expects the value in the gadget's
  427. LeftEdge field to be relative to the right window border.
  428.  
  429. There is a special kind of GREL Boopsi gadget called a custom
  430. relativity gadget.  For this type of gadget, Intuition expects the
  431. values in the LeftEdge, TopEdge, Width, and Height fields to be
  432. absolute measurements, just like the values Intuition expects in
  433. these fields for non-GREL gadgets.
  434.  
  435. Setting the GFLG_RELSPECIAL bit in the Gadget.Flags field marks the
  436. gadget as a custom relativity gadget.  The best way to set this bit
  437. is by setting the GA_RelSpecial attribute to TRUE when creating the
  438. gadget.
  439.  
  440.  
  441. Disabled Imagery
  442.  
  443. Certain gadget types support using a Boopsi Image as its imagery.
  444. These gadget types include the non-Boopsi boolean gadget, the
  445. frbuttonclass gadget, and the buttongclass gadget (This can also
  446. include private gadget classes that support the GA_Image attribute).
  447. The Gadget structure contains a field called GadgetRender which can
  448. point to a Boopsi Image object (the GFLG_GADGIMAGE bit in the
  449. Gadget.Flags field should also be set, see the``Intuition Gadgets''
  450. chapter of the RKRM:Libraries for more information).  Intuition uses
  451. this image as the gadget's imagery.
  452.  
  453. When a gadget uses this scheme for its imagery, Intuition sends
  454. IM_DRAW (and IM_DRAWFRAME) messages to the image object.  These
  455. imageclass methods not only tell a Boopsi image to render itself,
  456. they also tell the image which state to draw itself.  Some examples
  457. of image states include normal, selected, and disabled.
  458.  
  459. Prior to Release 3, when Intuition sent a draw message to one of
  460. these images, it only used the normal and selected states.  If the
  461. image was disabled, Intuition told the image to draw itself as normal
  462. or selected and would render the standard ``ghosted'' imagery over
  463. the gadget.
  464.  
  465. Under Release 3, Intuition will use the disabled state as well, but
  466. only if the gadget's image object supports it.  When Intuition adds
  467. the gadget to a window, Intuition tests the IA_SupportsDisabled
  468. attribute of the gadget's image object.  This imageclass attribute
  469. was introduced in Release 3.  If this attribute is TRUE, the image
  470. supports disabled imagery (both the IDS_DISABLED and
  471. IDS_SELECTEDDISABLED states), so Intuition sets the GFLG_IMAGEDISABLE
  472. flag in the Gadget structure's Flags field.  Intuition uses this flag
  473. to tell if it should use the image's disabled state in the
  474. IM_DRAW/IM_DRAWFRAME message.
  475.  
  476. As the IA_SupportsDisabled attribute is a fixed property of an image
  477. object, it is only accessible using the OM_GET method.  An
  478. application cannot set it or clear it.
  479.  
  480.  
  481. Frameiclass Frame Types
  482.  
  483. For Release 3, the Boopsi image class frameiclass acquired a new
  484. attribute, IA_FrameType.  This attribute allows applications to
  485. choose a frame style for a frame image.  Currently there are four
  486. styles available:
  487.  
  488.     FRAME_DEFAULT - This is the default frame which was the only
  489.     available frame in V37.  It has thin edges.
  490.  
  491.     FRAME_BUTTON - This is the imagery for the standard button
  492.     gadget. It has thicker sides and nicely edged corners.
  493.  
  494.     FRAME_RIDGE - This is a ridge commonly used by standard string
  495.     gadgets.  When recessed (using the frameiclass attribute
  496.     IA_Recessed), this image appears as a groove.  Applications and
  497.     utilities commonly use the recessed image to visually group
  498.     objects on the display.
  499.  
  500.     FRAME_ICONDROPBOX - This broad ridge is the system standard
  501.     imagery for icon ``drop boxes'' inside of an AppWindow (see the
  502.     ``Workbench and Icon Library'' chapter of the RKRM:Libraries for
  503.     more information on AppWindows).  The recessed version has no
  504.     standard purpose.
  505.  
  506.  
  507.         [Figure 3]
  508.  
  509.  
  510.  
  511. Additions to Sysiclass
  512.  
  513. The class of system images, sysiclass, gained two new images for
  514. Release 3, a menu check mark image and an Amiga key image
  515. (respectively, MENUCHECK and AMIGAKEY from
  516. <intuition/imageclass.h>):
  517.  
  518.  
  519.         [Figure 4]
  520.  
  521.  
  522.  
  523. This class also gained a new attribute called
  524. SYSIA_ReferenceFont.  This attribute, which is only accessible
  525. with the OM_NEW method, points to a TextFont structure.  The
  526. MENUCHECK and AMIGAKEY images will use this font to figure out
  527. how large to make the image.  This attribute overrides the
  528. SYSIA_DrawInfo font and SYSIA_Size attributes when calculating
  529. the dimensions of the image.
  530.  
  531.  
  532. About the Example
  533.  
  534. The example at the end of this article, relative.c, uses three
  535. features mentioned in this article.  The example implements a
  536. private subclass of gadgetclass.  The new class utilizes the
  537. frameiclass IA_FrameType attribute to create a button gadget.
  538. The class also takes advantage of the custom relativity feature.
  539. The example opens a window placing one of these gadgets in the
  540. middle of the window, sizing the gadget relative to the window's
  541. dimensions.
  542.  
  543. The example also illustrates the gadget help feature of
  544. Intuition.  When the private class dispatcher receives a
  545. GM_HELPTEST message, it returns the bitwise AND of GMR_HELPCODE
  546. and the value 0xC0DE.  When the example receives an
  547. IDCMP_GADGETHELP message at the window's message port, the
  548. example examines the message to find out what object triggered
  549. the help message and printf()s the results.
  550.